package orm

import (
	"fmt"
	"strings"

	"github.com/go-xorm/xorm"
	"github.com/jinzhu/gorm"
	"gopkg.in/mgo.v2"
)

type EngineXorm struct {
	*xorm.Engine
}
type EngineGorm struct {
	*gorm.DB
}
type EngineMgo struct {
	*mgo.Database
}

var Mysql = map[string]interface{}{
	"gorm": createGorm,
	"xorm": createXorm,
}

var Mongodb = map[string]interface{}{
	"mgo": createMgo,
}

//orm库
type DbEngineType int8
type DbEngineName string

const (
	DbMysqlEngineTypeXorm DbEngineType = iota
	DbMysqlEngineTypeGorm
	DbMongoEngineTypeMgo
)

const (
	DbMysqlEngineNameXorm DbEngineName = "xorm"
	DbMysqlEngineNameGorm DbEngineName = "gorm"
	DbMongoEngineNameMgo  DbEngineName = "mgo"
)

var orms = map[DbEngineName]DbEngineType{
	DbMysqlEngineNameXorm: DbMysqlEngineTypeXorm,
	DbMysqlEngineNameGorm: DbMysqlEngineTypeGorm,
	DbMongoEngineNameMgo:  DbMongoEngineTypeMgo,
}

//反射执行,性能较低
func OrmReflect(i interface{}, addr string) {

	//rval := reflect.ValueOf(i)
	//rtype := reflect.TypeOf(i)
	//if rval.Kind() == reflect.Func  {
	//
	//	params := make([]reflect.Value, 1)
	//	params[0] = reflect.ValueOf(addr)
	//	rs := rval.Call(params)
	//
	//	if rtype.Out(0).String() == "*xorm.Engine" {
	//		xorm := rs[0].Interface().(*xorm.Engine)
	//	}
	//}
}

func createXorm(addr string) *EngineXorm {
	engine, err := xorm.NewEngine("mysql", addr)

	if err != nil {
		fmt.Println("createXorm error:", err.Error())
		panic(err)
	} else {
		engine.SetMaxIdleConns(100)
		engine.SetMaxOpenConns(200)
	}
	return &EngineXorm{engine}
}

func createGorm(addr string) *EngineGorm {
	engine, err := gorm.Open("mysql", addr)
	//defer engine.Close()
	if err != nil {
		panic(err)
	} else {
		engine.DB().SetMaxIdleConns(100)
		engine.DB().SetMaxOpenConns(200)
		return &EngineGorm{engine}
	}
}

func createMgo(addr string, dbname string) *EngineMgo {
	MongodbSession, err := mgo.Dial(addr)
	//MongodbSession.SetPoolLimit()
	if err != nil {
		panic(fmt.Sprintln("mongodb连接失败", addr, err))
	}
	if strings.Contains(addr, "replicaSet") {
		MongodbSession.SetMode(mgo.Eventual, true)
	}

	return &EngineMgo{MongodbSession.DB(dbname)}
}
